package com.jbp.job;

import java.util.Date;
import java.util.List;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.jbp.model.*;
import com.jbp.service.SkillOrderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;


/**
 * 取消超时未支付，或者支付后未确认的订单
 * 逻辑：
 * 1. 取消超过15分钟未支付的订单
 * 2. 取消支付后，15分钟未被接单的订单
 */
//@Component
public class CancelTimeoutOrderJob {
    private static final Logger logger = LoggerFactory.getLogger(CancelTimeoutOrderJob.class);

    @Autowired
    private SkillOrderService skillOrderService;

    @Scheduled(fixedDelay = 1000 * 2)
    public void cancelTimeoutOrder() {
        // TODO: 读取配置，做时间上相关的校验：配置的最小时间，不能小于15分钟
        int timeoutMinutes = 15;
        Date timeoutDatetime = new Date(new Date().getTime() + timeoutMinutes * 60 * 1000);

        List<SkillOrder> skillOrders = skillOrderService.list(Wrappers.<SkillOrder>lambdaQuery()
                .nested(i -> i.eq(SkillOrder::getStatus, 0).le(SkillOrder::getCreateTime, timeoutDatetime))
                .or()
                .nested(i -> i.eq(SkillOrder::getStatus, 1).le(SkillOrder::getPayTime, timeoutDatetime)));

        logger.debug("发现{}个超时的订单", skillOrders.size());

        for (SkillOrder skillOrder : skillOrders) {
            Integer skillOrderId = skillOrder.getId();
            Integer origionStatus = skillOrder.getStatus();
            // 避免处理某个skillOrder出现异常时，影响后面skillOrder的处理，所以加了异常捕获逻辑
            try {
                // 取消订单
                logger.debug("start to cancel timeout order with id: {} and status : {}", skillOrder.getId(),
                        skillOrder.getStatus());
                skillOrderService.timeoutCancel(skillOrderId, origionStatus);

                // 测试异常处理逻辑
                // throw new RuntimeException("test stop");
            } catch (Exception e) {
                String msg = String.format("cancel skill order error with id %s", skillOrderId);
                logger.error(msg, e);
            }
            // 单元测试时，避免修改所有数据使用break
            // break;
        }

        // 等待3秒继续执行
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}
